/* 
 * File:   GeneticOperators.h
 * Author: jcrada
 *
 * Created on April 7, 2009, 7:37 PM
 */

#ifndef _GENETICOPERATORS_H
#define	_GENETICOPERATORS_H

#include "Node.h"
#include "TreeOfNodes.h"
#include "RandomGsl.h"
#include "TreeGenerator.h"

namespace jcrada {

    class CrossoverOperator {
    private:
        RandomGsl* _random_crossover_point;
        RandomGsl* _random_node_selection;
        double _probability_select_functions;

    protected:
        virtual Node* crossoverPoint( const TreeOfNodes& parent );

        virtual RandomGsl& getRandomCrossoverPoint( ) const {
            return *_random_crossover_point;
        }

        virtual RandomGsl& getRandomNodeSelection( ) const {
            return *_random_node_selection;
        }


    public:
        CrossoverOperator( );
        virtual ~CrossoverOperator( );
        
        virtual void crossover( TreeOfNodes& son, const TreeOfNodes& daughter ) = 0;

        virtual void setProbabilityToSelectFunctions( double probability ) {
            this->_probability_select_functions = probability;
        }

        virtual double getProbabilityToSelectFunctions( ) const {
            return this->_probability_select_functions;
        }
    };

    class MutationOperator {
    private:
        int _max_mutation_depth;
        RandomGsl* _random_mutation_point;
        RandomGsl* _random_method;
    protected:

        RandomGsl& getRandomMutationPoint( ) const {
            return *_random_mutation_point;
        }

        RandomGsl& getRandomMethod( ) const {
            return *_random_method;
        }

    public:
        MutationOperator( );
        virtual ~MutationOperator( );
        virtual TreeOfNodes* mutate( const TreeOfNodes& victim, TreeGenerator& mutation_generator ) = 0;

        virtual void setMaxMutationDepth( int depth ) {
            this->_max_mutation_depth = depth;
        }

        virtual int getMaxMutationDepth( ) const {
            return this->_max_mutation_depth;
        }
    };

    class ReproductionOperator {
    public:
        ReproductionOperator( );
        virtual ~ReproductionOperator( );
        virtual TreeOfNodes* reproduce( const TreeOfNodes& survivor ) = 0;
    };
}

#endif	/* _GENETICOPERATORS_H */

